package com.libnetwork.websocketservice

import android.util.Log
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.libnetwork.Network
import com.libnetwork.httpservice.HttpService
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okio.ByteString

class WebSocketService : WebSocketListener() {
    companion object {
        const val TAG = "WebSocketService"

        val instance: WebSocketService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            WebSocketService()
        }
    }

    private var webSocket: WebSocket? = null

    var isConnected: Boolean = false

    init {
        ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onCreate(owner: LifecycleOwner) {
                super.onCreate(owner)

                Log.i(TAG, "webSocket application onCreate")
            }

            override fun onStart(owner: LifecycleOwner) {
                super.onStart(owner)

                Log.i(TAG, "webSocket application onStart")
            }

            override fun onResume(owner: LifecycleOwner) {
                super.onResume(owner)

                Log.i(TAG, "webSocket application onResume")

                connect()
            }

            override fun onPause(owner: LifecycleOwner) {
                super.onPause(owner)

                Log.i(TAG, "webSocket application onPause")

                disconnect()
            }

            override fun onStop(owner: LifecycleOwner) {
                super.onStop(owner)

                Log.i(TAG, "webSocket application onStop")
            }

            override fun onDestroy(owner: LifecycleOwner) {
                super.onDestroy(owner)

                Log.i(TAG, "webSocket application onDestroy")

                disconnect()
            }
        })
    }

    fun initWebSocket() {
    }

    fun connect() {
        webSocket = Network.instance.appID?.let { appID ->
            Network.instance.serviceAddressRepository?.data?.webSocketUrl?.let { webSocketUrl ->
                val request =
                    Request.Builder().url("$webSocketUrl/$appID")
                        .build()
                HttpService.instance.okHttpClient.newWebSocket(request, this)
            }
        }
    }

    fun disconnect() {
        webSocket?.close(1000, null)
        webSocket = null
    }

    override fun onOpen(webSocket: WebSocket, response: Response) {
        Log.i(TAG, "webSocket onOpen")

        isConnected = true
    }

    override fun onMessage(webSocket: WebSocket, text: String) {
        Log.i(TAG, "webSocket onMessage text: $text")
    }

    override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
        Log.i(TAG, "webSocket onMessage bytes: $bytes")
    }

    override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
        Log.i(TAG, "webSocket onClosing code: $code, reason: $reason")
    }

    override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
        Log.i(TAG, "webSocket onClosed code: $code, reason: $reason")

        isConnected = false
    }

    override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
        Log.i(TAG, "webSocket onFailure")
        t.printStackTrace()

        isConnected = false
    }
}